the biggest problem with abstractionless is that it still needs loops or general recursive operators, requiring a lot of
explicit abstraction still.

array languages can do away with most loops

One could have a "dimensionality" type system. So if an array is 1d, then a scalar is 0d.

All function have dim types, e.g. * is 0d * 0d = 0d
if one of its args is actually 1d, then the result also is 1d, and the operator contains an implicit loop.

This perculates thru, e.g. vec*2+1 first does a loop to double each element of vec, then the resulting array
is looped over again (making this 1 loop is optimisation).

If you do vec*vec, that would result in a 2d vec, but maybe just keeping this 1d is more useful?

So this covers mapping, but what about filter/fold?

filter can almost be done with normal if-then's e.g:

if vec>5 then vec else nil

creates a resulting vector with numbers or nils, and the nils can then maybe be filtered
out automatically. Or there can be a special "bottom" value that is not put into the list
at all, and is the default for the else case, so:

if vec>5 then vec

would already result in a filtered list. There's be no concern wether "vec" has identity,
since even if they are not the same, it will still work... assuming the above keeps it 1d, not 2d

or you could even just have vec>5, where it is assumed that > returns the lhs if true, and nil
if false...

folds could be defined non-haskell like, by simply saying its defined on list of >=2, on list of
size 1 it just returns its single element (ok for * and +), and empty list it returns 0 (ok for +,
not for *). What does K do for */[] ? it gives some sort of empty special value

maps are nicely compositional, but how to make folds compositional?
if we wanted to fold \(x,y).x*y+3 onto a list, how would we do it without a function def?

an alternative to */vec is vec*`1, where `1 denotes an accumulator value. So it works just
like a normal map, except the `1 is replaced by previous results all the time, and is also
the end result. But this still does not allow tying in 3.

K has the operation that instead of a fold, gives all its intermediate results, but that still
doesn't help inserting the +3

so it has to be 

fold vec*`1+3

But what if you wanted to loop additional variables? K's scan \ operation can help if you want to
do additional things with the intermediate variables, but not if the influence the fold itself.
though frankly, most things you want to do you can probably split up.







define calc_iterations x:real y:real do
  xc = x
  yc = y
  i = 0
  while i<maxdepth and x*x+y*y<16.0 do   -- |z| < 4
    t = x
    x = x*x-y*y+xc                       -- z = z*z + c
    y = (t+t)*y+yc
    i = i+1
  end
  return i
end


b:4>@[n;&0n=n:+/_sqr 50{c+(-/x*x;2*/x)}/c:+,/(-1.5+2*(!w)%w),/:\:-1+2*(!w)%w:200;:;4];`mandel.pbm 6:"P4\n",(5:2#w),"\n",_ci 2_sv'-1 8#,/+(2#w)#b


// assumes lazy semantics

length (take 256 (takewhile x*x+y*y<16.0))
	x = first r
	y = second r
	r = generate [x*x-y*y+xc, (x+x)*y+yc]
		x = first `xys
		y = second `xys
		xc = first xys -- how does this work on the inner array? yes, if there's a very strict type system difference between 1d/2d/3d arrays, not just arbitrarily nested lists
		yc = second xys
		  xys = -- 3d array: 2d array of pairs 



define qsort [] -> []
define qsort [pivot] + rest ->
  (qsort filter x in rest where lt x pivot) + [pivot] +
  (qsort filter x in rest where not lt x pivot)


